#!/bin/sh
#=======================================================================
#        FILE: tests.sh
# DESCRIPTION: Runs test suite under all supported versions of Python
#              and displays failures when encountered.
#       NOTES: Don't try to get too fancy with this script. All changes
#              should be tested under `bash`, `dash`, and `ksh` shell
#              implementations.
#=======================================================================


#--- FUNCTION ----------------------------------------------------------
#        NAME: call_command
# DESCRIPTION: Calls given command and displays appropriate message.
#              * When a command is successful, the success message is
#                echoed and the $command_ok flag is set to 1 (output is
#                captured and not displayed).
#              * When a command is missing, "(not found)" is echoed and
#                the $command_missing flag is set to 1.
#              * When a command fails, its output is echoed and the
#                script terminates early.
#
# PARAMETER 1: Command to execute.
# PARAMETER 2: Start message.
# PARAMETER 3: Success message.
# PARAMETER 4: Failure message.
#-----------------------------------------------------------------------
call_command ()
{
    echo -n "$2" # Start message.
    output=$($1 2>&1)  # Call command, capture stderr as $output.
    exitstatus=$?  # Get exit status of from completed command.
    if [ $exitstatus -eq 0 ]
    then
        echo "$3"  # Success message.
        command_ok=1  # Set flag.
    else
        if [ $exitstatus -eq 127 ]  # 127 is "command not found".
        then
            echo "(not found)"
            command_missing=1  # Set flag.
        else
            echo "$4"  # Failure message.
            echo ""
            echo "$output on $1" 1>&2  # Send $output to stderr.
            exit $exitstatus  # <- EXIT!
        fi
    fi
}


#--- FUNCTION ----------------------------------------------------------
#        NAME: call_runtests
# DESCRIPTION: Calls runtests.py using specified version of Python.
# PARAMETER 1: Name of Python executable to use.
# PARAMETER 2: Interpreter options.
#-----------------------------------------------------------------------
call_runtests () {
    call_command "$1 $2 runtests.py" "$1 ... " "ok" "FAIL"
}


#-----------------------------------------------------------------------
# Translate code and run test suite in all supported versions of Python.
#-----------------------------------------------------------------------
# Backport source code for 2.x support.
call_command "python -B backport.py" "backporting ... " "done" "errors"

# Reset flags used by call_command.
command_ok=0
command_missing=0

# Execute tests.
call_runtests python3.3 -B  # The -B option turns off writing .py[co]
call_runtests python3.2 -B  # files (not supported in 2.5 or earlier).
call_runtests python3.1 -B
call_runtests python3.0 -B
call_runtests python2.7 -B
call_runtests python2.6 -B
call_runtests python2.5
call_runtests python2.4

# Display appropriate success/failure message.
echo "----------------------------------------------------------------------"
if [ $command_ok -eq 1 ]  # If one or more commands successful.
then
    if [ $command_missing -eq 1 ]  # If one or more commands missing.
    then
        echo "Tests passed but some supported versions of Python are missing and"
        echo "could not be tested."
        echo ""
        echo "FAILED (missing versions)"
    else
        echo "Ran all tests on all supported Python versions. Looks good!"
        echo ""
        echo "OK"
    fi
else
    # The call_command function terminates this script early when a
    # command fails.  So when the script behaves as expected, this
    # `else` should never be evaluated.
    echo "The shell script was unable to run tests."
    echo ""
    echo "FAILED (error in $0)"
fi
# Note: Above, we call echo multiple times to get consistent line-break
# behavior across common shells (\n and -e are not cross-shell).
